package com.cloudy.security;

import com.cloudy.s3.request.S3Request;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import static com.cloudy.utility.CloudyUtility.createStringToSign;

public class S3RequestSigner {
    private javax.crypto.Mac mac = null;
    private javax.crypto.spec.SecretKeySpec signingKey = null;
    private String keyId;

    public S3RequestSigner() {
        try {
            this.keyId = AccessIdentifiers.getAccessKeyID();
            setKey(AccessIdentifiers.getSecretAccessKey());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public String sign(String data) throws Exception {
//        System.out.println(data);
        // Signed String must be BASE64 encoded.
        byte[] signBytes = mac.doFinal(data.getBytes("UTF8"));
        String signature = encodeBase64(signBytes);
        String result = "AWS " + keyId + ":" + signature;
        result = result.substring(0,result.length()-1);
//        System.out.println("Start "+result+ " End");
        return result;
    }

    public static String encodeBase64(byte[] data) {
        String base64 = new sun.misc.BASE64Encoder().encodeBuffer(data);
        if (base64.endsWith("\r\n")) base64 = base64.substring(0, base64.length() - 2);
        return base64;
    }

    public void setKey(String AWSSecretKey) throws Exception {
        mac = Mac.getInstance("HmacSHA1");
        byte[] keyBytes = AWSSecretKey.getBytes("UTF8");
        signingKey = new SecretKeySpec(keyBytes, "HmacSHA1");
        mac.init(signingKey);
    }

    public void sign(S3Request request) {
        String stringToSign = createStringToSign(request);
        try {
            String signature = sign(stringToSign);
            request.putSignature(signature);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
